package dipl.visualizer.graphics.shape;

import dipl.algorithm.math.primitive.Point2d;
import dipl.algorithm.math.fp.primitive.Point2df;
import dipl.algorithm.exception.ArgumentException;
import dipl.visualizer.graphics.PaintContext;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Stroke;

public class Polygon2dShape extends AbstractShape {

	//
	// CONSTRUCTOR METHODS
	//
	
	/// <summary>
	/// Constructs shape from given polygon points. They are assumed to be ordered clockwise.
	/// The shape will also paint polygon vertices.
	/// </summary>
	/// <param name="name">name of shape</param>
	/// <param name="polygon">polygon points</param>
	/// <param name="polygonColor">color of polygon lines</param>
	/// <param name="vertexColor">color of polygon vertices</param>
	/// <param name="font">font </param>
	public Polygon2dShape(
		String name,
		Point2d[] polygon,
		Color polygonColor,
		Color vertexColor,
		Font font
	) {
		super( name, polygonColor );
		this.polygon = new Point2df[polygon.length];
		for( int i = 0; i < polygon.length; i++ ) {
			this.polygon[i] = new Point2df( polygon[i].x.doubleValue(), polygon[i].y.doubleValue() );
		}
		this.paintVertices = true;
		this.vertexColor = vertexColor;
		this.stroke = new BasicStroke( 2.0f );
		this.font = font;
	}

	/// <summary>
	/// Constructs shape from given polygon points. They are assumed to be ordered clockwise.
	/// The shape will NOT paint polygon vertices.
	/// </summary>
	/// <param name="name">name of shape</param>
	/// <param name="polygon">polygon points</param>
	/// <param name="polygonColor">color of polygon lines</param>
	public Polygon2dShape( String name, Point2d[] polygon, Color polygonColor ) throws ArgumentException {
		super( name, polygonColor );
		if( polygon == null || polygon.length == 0 )
			throw new ArgumentException( "No polygon points given." );

		this.polygon = new Point2df[polygon.length];
		for( int i = 0; i < polygon.length; i++ ) {
			this.polygon[i] = new Point2df( polygon[i].x.doubleValue(), polygon[i].y.doubleValue() );
		}
		this.paintVertices = false;
		this.stroke = new BasicStroke( 2.0f );
		this.font = null;
	}

	//
	// PUBLIC METHODS
	//
	
	@Override
	public void Paint( PaintContext pc ) {
		int i;

		// draw polygon lines
		int n = polygon.length;
		pc.SetColor( color );
		pc.SetStroke( stroke );
		for( i = 0; i < polygon.length; i++ ) {
			pc.DrawLine( polygon[i], polygon[(i+1)%n] );
		}

		if( !paintVertices )
			return;

		// paint poygon vertices
		pc.SetColor( vertexColor );
		pc.SetFont( font );
		for( i = 0; i < polygon.length; i++ ) {
			pc.FillRectangle( polygon[i].x-0.01, polygon[i].y+0.01, 0.02, 0.02 );
			pc.DrawString( Integer.toString( i ), polygon[i].x+0.02, polygon[i].y+0.02 );
		}
	}

	//
	// PROPERTIES
	//

	@Override
	public Point2df PointOnShape() {
		return polygon[0];
	}

	//
	// MEMBERS
	//

	/// <summary>
	/// polygon points (ordered clockwise)
	/// </summary>
	private Point2df[] polygon;
	/// <summary>
	/// whether or not to paint vertices
	/// </summary>
	private boolean paintVertices;
	/// <summary>
	/// color of polygon vertices
	/// </summary>
	private Color vertexColor;
	/// <summary>
	/// Font
	/// </summary>
	private Font font;
	/**
	 * line stroke
	 */
	Stroke stroke;
}
